﻿using DevExpress.ExpressApp.EFCore.Updating;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using DevExpress.Persistent.BaseImpl.EF.PermissionPolicy;
using DevExpress.Persistent.BaseImpl.EF;
using DevExpress.ExpressApp.Design;
using DevExpress.ExpressApp.EFCore.DesignTime;
using Microsoft.Extensions.Configuration;

namespace XAF_EFCore_Sample.Module.BusinessObjects;

// This code allows our Model Editor to get relevant EF Core metadata at design time.
// For details, please refer to https://supportcenter.devexpress.com/ticket/details/t933891.
public class XAF_EFCore_SampleContextInitializer : DbContextTypesInfoInitializerBase
{
    protected override DbContext CreateDbContext()
    {
        var optionsBuilder = new DbContextOptionsBuilder<XAF_EFCore_SampleEFCoreDbContext>()
            .UseSqlServer(";")
            .UseChangeTrackingProxies()
            .UseObjectSpaceLinkProxies();
        return new XAF_EFCore_SampleEFCoreDbContext(optionsBuilder.Options);
    }
}
//This factory creates DbContext for design-time services. For example, it is required for database migration.
public class XAF_EFCore_SampleDesignTimeDbContextFactory : IDesignTimeDbContextFactory<XAF_EFCore_SampleEFCoreDbContext>
{
    public XAF_EFCore_SampleEFCoreDbContext CreateDbContext(string[] args)
    {
        var configutionBuilder = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json")
            .Build();

        var optionsBuilder = new DbContextOptionsBuilder<XAF_EFCore_SampleEFCoreDbContext>();
        optionsBuilder.UseSqlServer(configutionBuilder.GetConnectionString("ConnectionString"));
        optionsBuilder.UseChangeTrackingProxies();
        optionsBuilder.UseObjectSpaceLinkProxies();
        return new XAF_EFCore_SampleEFCoreDbContext(optionsBuilder.Options);
    }
}
[TypesInfoInitializer(typeof(XAF_EFCore_SampleContextInitializer))]
public class XAF_EFCore_SampleEFCoreDbContext : DbContext
{
    public XAF_EFCore_SampleEFCoreDbContext(DbContextOptions<XAF_EFCore_SampleEFCoreDbContext> options) : base(options)
    {
    }
    //public DbSet<ModuleInfo> ModulesInfo { get; set; }
    public DbSet<ModelDifference> ModelDifferences { get; set; }
    public DbSet<ModelDifferenceAspect> ModelDifferenceAspects { get; set; }
    public DbSet<PermissionPolicyRole> Roles { get; set; }
    public DbSet<XAF_EFCore_Sample.Module.BusinessObjects.ApplicationUser> Users { get; set; }
    public DbSet<XAF_EFCore_Sample.Module.BusinessObjects.ApplicationUserLoginInfo> UserLoginInfos { get; set; }
    public DbSet<UserTag> UserTags { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.HasChangeTrackingStrategy(ChangeTrackingStrategy.ChangingAndChangedNotificationsWithOriginalValues);
        modelBuilder.Entity<XAF_EFCore_Sample.Module.BusinessObjects.ApplicationUserLoginInfo>(b =>
        {
            b.HasIndex(nameof(DevExpress.ExpressApp.Security.ISecurityUserLoginInfo.LoginProviderName), nameof(DevExpress.ExpressApp.Security.ISecurityUserLoginInfo.ProviderUserKey)).IsUnique();
        });
        modelBuilder.Entity<ModelDifference>()
            .HasMany(t => t.Aspects)
            .WithOne(t => t.Owner)
            .OnDelete(DeleteBehavior.Cascade);

        modelBuilder.Entity<UserTag>()
            .HasOne(t => t.User)
            .WithMany(u => u.Tags)
            .OnDelete(DeleteBehavior.Cascade);
    }
}
